/**
 * 算式抽象类 - 构造版本2.0
 * 
 * 设计特点：
 * 1. 抽象类，定义算式的通用属性和方法
 * 2. 提供抽象方法让子类实现特定行为
 * 3. 封装加法和减法的通用逻辑
 * 4. 支持多态性，便于扩展
 * 
 * 业务规则：
 * - 加法结果不超过100
 * - 减法差不小于0
 * - 支持负数和100以上的数
 */
package edu.scut.oop.exercise.v2;

public abstract class Expression {
    // 保护成员变量，子类可直接访问
    protected int num1;
    protected int num2;
    protected int result;
    
    /**
     * 构造函数
     * @param num1 操作数1
     * @param num2 操作数2
     */
    public Expression(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
        this.result = calculate(); // 自动计算结果
    }
    
    /**
     * 计算结果 - 子类必须实现
     * @return 计算结果
     */
    public abstract int calculate();
    
    /**
     * 格式化算式（不含答案）
     * @return 格式化后的算式字符串
     */
    public String formatExpression() {
        String num2Str;
        if (num2 < 0) {
            num2Str = "(" + num2 + ")";
        } else {
            num2Str = String.valueOf(num2);
        }
        return String.format("%d %s %s", num1, getOperatorSymbol(), num2Str);
    }
    
    /**
     * 格式化算式（含答案）
     * @return 格式化后的算式字符串（含答案）
     */
    public String formatWithAnswer() {
        String num2Str;
        if (num2 < 0) {
            num2Str = "(" + num2 + ")";
        } else {
            num2Str = String.valueOf(num2);
        }
        return String.format("%d %s %s = %d", num1, getOperatorSymbol(), num2Str, result);
    }
    
    /**
     * 验证算式是否有效
     * @return true表示有效，false表示无效
     */
    public boolean isValid() {
        // 基本验证：确保结果计算正确
        if (isAddition()) {
            return result <= 100; // 加法结果不超过100
        } else if (isSubtraction()) {
            return result >= 0;   // 减法差不小于0
        }
        return false;
    }
    
    /**
     * 检查算式是否可以交换操作数
     * @return true表示可以交换
     */
    public boolean canSwapOperands() {
        // 默认实现：不允许交换
        return false;
    }
    
    /**
     * 交换操作数
     * @return 交换操作数后的新算式
     */
    public Expression swapOperands() {
        // 默认实现：抛异常
        throw new UnsupportedOperationException("此算式类型不支持交换操作数");
    }
    
    /**
     * 判断是否为加法 - 子类必须实现
     * @return true表示是加法
     */
    public abstract boolean isAddition();
    
    /**
     * 判断是否为减法 - 子类必须实现
     * @return true表示是减法
     */
    public abstract boolean isSubtraction();
    
    /**
     * 获取操作符符号 - 子类必须实现
     * @return 操作符符号
     */
    public abstract String getOperatorSymbol();
    
    // Getter和Setter方法
    public int getNum1() {
        return num1;
    }
    
    public void setNum1(int num1) {
        this.num1 = num1;
        this.result = calculate(); // 重新计算结果
    }
    
    public int getNum2() {
        return num2;
    }
    
    public void setNum2(int num2) {
        this.num2 = num2;
        this.result = calculate(); // 重新计算结果
    }
    
    public int getResult() {
        return result;
    }
    
    public void setResult(int result) {
        this.result = result;
    }
    
    /**
     * 重写equals方法，基于算式的数学意义比较
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        
        Expression that = (Expression) obj;
        return num1 == that.num1 && 
               num2 == that.num2 && 
               result == that.result &&
               this.getClass() == that.getClass();
    }
    
    /**
     * 重写hashCode方法
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + num1;
        hash = 31 * hash + num2;
        hash = 31 * hash + result;
        hash = 31 * hash + getClass().hashCode();
        return hash;
    }
    
    /**
     * 重写toString方法
     */
    @Override
    public String toString() {
        return formatWithAnswer();
    }
}